//
//  TurboMac.c
//  TurboMac
#include "TurboMac.h"
#include <IOKit/IOLib.h>

#define super IOService
OSDefineMetaClassAndStructors(TurboMac, IOService);

extern "C" kern_return_t TurboMac_start(kmod_info_t * ki, void *d);
extern "C" kern_return_t TurboMac_stop(kmod_info_t * ki, void *d);

const uint32_t IA32_PERF_CTL = 0x199;
const uint32_t MSR_PKG_POWER_LIMIT = 0x610;

bool TurboMac::init(OSDictionary* dict) {
    bool res = super::init(dict);
    IOLog("Initializing TurboMac...\n");
    return res;
}

IOService* TurboMac::probe(IOService *provider, SInt32 *score) {
    IOService* res = super::probe(provider, score);
    IOLog("Probing TurboMac...\n");
    return res;
}

bool TurboMac::start(IOService *provider)
{
    bool res = super::start(provider);
    IOLog("Starting TurboMac...");
    wrmsr64(IA32_PERF_CTL, 0x2100);
//    wrmsr64(MSR_PKG_POWER_LIMIT, 0x83e800dd8f00);
    wrmsr64(MSR_PKG_POWER_LIMIT, 0x8d832000dd81e0);
//    wrmsr64(MSR_PKG_POWER_LIMIT, 0xffffff00ffffff);
    
    IOLog("TurboMac fully initialized.");
    return res;
}

void TurboMac::stop(IOService *provider) {
    super::stop(provider);
    IOLog("Stopping TurboMac...");
}

extern "C" kern_return_t TurboMac_start(kmod_info_t * ki, void *d) {
    IOLog("Starting!");
    return KERN_SUCCESS;
}

extern "C" kern_return_t TurboMac_stop(kmod_info_t *ki, void *d) {
    IOLog("Stopping!");
    return KERN_SUCCESS;
}
